package com.mao.crowd.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mao.crowd.constant.CrowdConstant;
import com.mao.crowd.exception.EditAcctDuplicatedException;
import com.mao.crowd.exception.LoginAcctDuplicatedException;
import com.mao.crowd.exception.LoginFailException;
import com.mao.crowd.mapper.AdminMapper;
import com.mao.crowd.service.api.AdminService;
import com.mao.crowd.util.CrowdUtil;
import entity.Admin;
import entity.AdminExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author: Administrator
 * @description:
 * @cteate 2021-05-26-21:07
 */

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public void saveAdmin(Admin admin) {
//        用户密码加密
        String userPswd = admin.getUserPswd();
        // userPswd = CrowdUtil.md5(userPswd);
        userPswd = passwordEncoder.encode(userPswd);
        admin.setUserPswd(userPswd);
//        生成用户创建时间
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = simpleDateFormat.format(date);
        admin.setCreateTime(createTime);
//        保存用户
        try {
            adminMapper.insert(admin);
        }catch (Exception e){
            if (e instanceof DuplicateKeyException){
                throw new LoginAcctDuplicatedException(CrowdConstant.MESSAGE_LOGINACCT_DUPLICATED);
            }
        }
    }

    @Override
    public List<Admin> getAll() {
//        选取一个空对象，就可以返回表中所有的对象
        return adminMapper.selectByExample(new AdminExample());
    }

    @Override
    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
//        调用PageHelper的开启分页方法
        PageHelper.startPage(pageNum,pageSize);
//        执行查询
        List<Admin> admins = adminMapper.selectAdminByKeyWord(keyword);

//        封装到PageInfo对象中
        return new PageInfo<>(admins);
        }

    @Override
    public Admin getAdminByLoginAccount(String loginAccount, String userPassword) {
//        根据登陆账号查询Admin对象
        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andLoginAcctEqualTo(loginAccount);
        List<Admin> admins = adminMapper.selectByExample(adminExample);

//        判断Admin对象是否为null
        if (admins == null || admins.size() == 0){
//        如果为null，则抛出loginFailedException
            throw new LoginFailException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
//        如果查到了多个对应的账号
        if(admins.size() > 1){
            throw new RuntimeException(CrowdConstant.MESSAGE_SYSTEM_ERROR_ACCOUNT_NOT_UNIQUE);
        }
//        如果list中的admin对象还是null
        Admin admin = admins.get(0);
        if (admin == null){
            throw new LoginFailException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
//        如果不为null，则取出数据库中保存的加密密码
        String userPswdFromDB = admin.getUserPswd();
//        将表单提交的密码进行加密
        String md5InputUserPswd = CrowdUtil.md5(userPassword);
//        比较密码
        if (!Objects.equals(md5InputUserPswd,userPswdFromDB)){
            //        结果不一致，则抛出loginFailedException
            throw new LoginFailException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        //        结果一致，返回Admin对象
        return admin;
    }

    @Override
    public void removeAdmin(Integer adminId) {

        adminMapper.deleteByPrimaryKey(adminId);
    }

    @Override
    public Admin getAdminById(Integer adminId) {
        Admin admin = adminMapper.selectByPrimaryKey(adminId);
        return admin;
    }

    @Override
    public void update(Admin admin) {
        try {
            adminMapper.updateByPrimaryKeySelective(admin);
        }catch(Exception e){
            if (e instanceof DuplicateKeyException){
                throw new EditAcctDuplicatedException(CrowdConstant.MESSAGE_EDITACCT_DUPLICATED);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAdminRoleRelationship(Integer adminId, List<Integer> roleIdList) {
        adminMapper.deleteOldRelationship(adminId);
        if ( roleIdList != null && roleIdList.size() > 0){
            adminMapper.insertNewRelationship(adminId,roleIdList);
        }
    }

    @Override
    public Admin getAdminByLoginAcct(String username) {

        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andLoginAcctEqualTo(username);
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        Admin admin = admins.get(0);
        return admin;
    }
}
